{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 查阅文档\n",
    "\n",
    "受篇幅所限，本书无法对所有用到的PyTorch函数和类一一详细介绍。读者可以查阅相关文档来做更深入的了解。\n",
    "\n",
    "## 查找模块里的所有函数和类\n",
    "\n",
    "当我们想知道一个模块里面提供了哪些可以调用的函数和类的时候，可以使用`dir`函数。下面我们打印`torch.cuda`模块中所有的成员或属性。 \n",
    "\n",
    "\n",
    "*吐槽一下，原书这里用的是 `nd.random` 模块，而 PyTorch 的模块组织确实很烂，这里挑一个稍微有点条理的做示范*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "attributes": {
     "classes": [],
     "id": "",
     "n": "1"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['BFloat16Storage', 'BFloat16Tensor', 'BoolStorage', 'BoolTensor', 'ByteStorage', 'ByteTensor', 'CharStorage', 'CharTensor', 'CudaError', 'DeferredCudaCallError', 'DoubleStorage', 'DoubleTensor', 'Event', 'FloatStorage', 'FloatTensor', 'HalfStorage', 'HalfTensor', 'IntStorage', 'IntTensor', 'LongStorage', 'LongTensor', 'PIPE', 'Popen', 'ShortStorage', 'ShortTensor', 'Stream', '_CudaBase', '_StorageBase', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_after_fork', '_check_capability', '_check_driver', '_cudart', '_dummy_type', '_free_mutex', '_get_device_index', '_host_allocator', '_in_bad_fork', '_initialization_lock', '_initialized', '_lazy_call', '_lazy_init', '_lazy_new', '_load_cudart', '_original_pid', '_queued_calls', '_register_after_fork', '_sleep', '_tls', '_utils', 'check_error', 'comm', 'contextlib', 'ctypes', 'cudaStatus', 'cudart', 'current_blas_handle', 'current_device', 'current_stream', 'default_stream', 'device', 'device_count', 'device_of', 'empty_cache', 'find_cuda_windows_lib', 'get_device_capability', 'get_device_name', 'get_device_properties', 'get_rng_state', 'get_rng_state_all', 'init', 'initial_seed', 'ipc_collect', 'is_available', 'manual_seed', 'manual_seed_all', 'max_memory_allocated', 'max_memory_cached', 'memory_allocated', 'memory_cached', 'nccl', 'nvtx', 'os', 'platform', 'profiler', 'raise_from', 'random', 'reset_max_memory_allocated', 'reset_max_memory_cached', 'seed', 'seed_all', 'set_device', 'set_rng_state', 'set_rng_state_all', 'sparse', 'stream', 'streams', 'synchronize', 'sys', 'threading', 'torch', 'traceback', 'warnings']\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "print(dir(torch.cuda))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通常我们可以忽略掉由`__`开头和结尾的函数（Python的特别对象）或者由`_`开头的函数（一般为内部函数）。通过其余成员的名字我们大致猜测出这个模块提供了各种对GPU的控制方法，包括可用设备数量（`device_count`）、GPU是否可用（`is_available`）、清空显存（`empty_cache`）等。\n",
    "\n",
    "## 查找特定函数和类的使用\n",
    "\n",
    "想了解某个函数或者类的具体用法时，可以使用`help`函数。让我们以`torch`中的`ones_like`函数为例，查阅它的用法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function ones_like:\n",
      "\n",
      "ones_like(...)\n",
      "    ones_like(input, dtype=None, layout=None, device=None, requires_grad=False) -> Tensor\n",
      "    \n",
      "    Returns a tensor filled with the scalar value `1`, with the same size as\n",
      "    :attr:`input`. ``torch.ones_like(input)`` is equivalent to\n",
      "    ``torch.ones(input.size(), dtype=input.dtype, layout=input.layout, device=input.device)``.\n",
      "    \n",
      "    .. warning::\n",
      "        As of 0.4, this function does not support an :attr:`out` keyword. As an alternative,\n",
      "        the old ``torch.ones_like(input, out=output)`` is equivalent to\n",
      "        ``torch.ones(input.size(), out=output)``.\n",
      "    \n",
      "    Args:\n",
      "        input (Tensor): the size of :attr:`input` will determine size of the output tensor.\n",
      "        dtype (:class:`torch.dtype`, optional): the desired data type of returned Tensor.\n",
      "            Default: if ``None``, defaults to the dtype of :attr:`input`.\n",
      "        layout (:class:`torch.layout`, optional): the desired layout of returned tensor.\n",
      "            Default: if ``None``, defaults to the layout of :attr:`input`.\n",
      "        device (:class:`torch.device`, optional): the desired device of returned tensor.\n",
      "            Default: if ``None``, defaults to the device of :attr:`input`.\n",
      "        requires_grad (bool, optional): If autograd should record operations on the\n",
      "            returned tensor. Default: ``False``.\n",
      "    \n",
      "    Example::\n",
      "    \n",
      "        >>> input = torch.empty(2, 3)\n",
      "        >>> torch.ones_like(input)\n",
      "        tensor([[ 1.,  1.,  1.],\n",
      "                [ 1.,  1.,  1.]])\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(torch.ones_like)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从文档信息我们了解到，`ones_like`函数会创建和输入`Tensor`形状相同且元素为1的新`Tensor`。我们可以验证一下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1., 1., 1.],\n",
       "        [1., 1., 1.]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.Tensor([[0, 0, 0], [2, 2, 2]])\n",
    "y = torch.ones_like(x)\n",
    "y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在Jupyter记事本里，我们可以使用`?`来将文档显示在另外一个窗口中。例如，使用`torch.rand?`将得到与`help(torch.rand)`几乎一样的内容，但会显示在额外窗口里。此外，如果使用`torch.rand??`，那么会额外显示该函数实现的代码。\n",
    "\n",
    "\n",
    "## 在PyTorch网站上查阅\n",
    "\n",
    "读者也可以在PyTorch的网站上查阅相关文档。访问PyTorch网站 [https://pytorch.org/](https://pytorch.org/) （如图2.1所示），点击网页顶部的下拉菜单“Docs”可查阅各个前端语言的接口。此外，也可以在点击网页右上方的搜索图标直接搜索函数或类名称。\n",
    "\n",
    "![PyTorch官方网站](../img/pytorch-website.png)\n",
    "\n",
    "图2.2展示了PyTorch网站上有关`ones_like`函数的文档。\n",
    "\n",
    "![PyTorch网站上有关`ones_like`函数的文档](../img/ones_like.png)\n",
    "\n",
    "## 小结\n",
    "\n",
    "* 遇到不熟悉的PyTorch API时，可以主动查阅它的相关文档。\n",
    "* 查阅PyTorch文档可以使用`dir`和`help`函数，或访问PyTorch官方网站。\n",
    "\n",
    "\n",
    "## 练习\n",
    "\n",
    "* 查阅`PyTorch`支持的其他操作。\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "## 扫码直达[讨论区](https://discuss.gluon.ai/t/topic/7116)\n",
    "\n",
    "![](../img/qr_lookup-api.svg)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
